package cn.yuanqiao.archive.api.service.impl;


import cn.yuanqiao.archive.api.domain.ReceiveRecord;
import cn.yuanqiao.archive.api.mapper.ReceiveRecordMapper;
import cn.yuanqiao.archive.api.service.DetectionApiService;
import cn.yuanqiao.archive.api.util.DetectionUtils;
import cn.yuanqiao.archive.appManager.domain.*;
import cn.yuanqiao.archive.appManager.mapper.TenantCategoryMapper;
import cn.yuanqiao.archive.appManager.mapper.TenantCodeListMapper;
import cn.yuanqiao.archive.appManager.mapper.TenantCodeRuleMapper;
import cn.yuanqiao.archive.appManager.mapper.TenantMdataListMapper;
import cn.yuanqiao.archive.appManager.service.ITenantSysConfigService;
import cn.yuanqiao.archive.appManager.service.ITenantSysDictTypeService;
import cn.yuanqiao.archive.detection.domain.*;
import cn.yuanqiao.archive.detection.mapper.*;
import cn.yuanqiao.archive.detection.util.DetectionUtil;
import cn.yuanqiao.archive.uploadfile.service.impl.FileService;
import cn.yuanqiao.archive.webservice.utils.XMLtoJsonUtils;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.utils.DateUtils;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.common.utils.SnowflakeIdGenerator;
import cn.yuanqiao.common.utils.StringUtils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DetectionApiServiceImpl implements DetectionApiService {
    @Value("${detectionUrl}")
    public String detectionUrl;
    @Autowired
    private ITenantSysConfigService sysConfigService;
    @Autowired
    private TenantCategoryMapper tenantCategoryMapper;
    @Autowired
    private TenantMdataListMapper mdataListMapper;
    @Autowired
    private DetectionSchemeMapper detectionSchemeMapper;
    @Autowired
    private DetectionObjectMapper detectionObjectMapper;
    @Autowired
    private ITenantSysDictTypeService sysDictTypeService;
    @Autowired
    private DetailLogsMapper detailLogsMapper;
    @Autowired
    private InspectionLogsMapper inspectionLogsMapper;
    @Autowired
    private InspectionRecordsMapper inspectionRecordsMapper;
    @Autowired
    private DetectionUtils detectionUtils;
    @Autowired
    private TenantCodeListMapper tenantCodeListMapper;

    @Autowired
    private TenantCodeRuleMapper tenantCodeRuleMapper;
    @Autowired
    private ReceiveRecordMapper receiveRecordMapper;
    private final Map<String,String> jianMap=new HashMap<String,String>(){{
        put("fileTitle","TITLE");//文件标题
        put("subHeading","FTM");//副标题
        put("genre","WZ");//文种
        put("referenceNumber","WH");//文号
        put("subjectTerm","ZTC");//主题词
        put("masterSend","ZHUSONG");//主送
        put("sendCopyTo","CHS");//抄送
        put("responsiblePerson","ZRZ");//责任者
        put("Date","RQ");//日期
        put("degreeOfUrgency","JJCD");//紧急程度
        put("securityClass","MJ");//密级
        put("confidentialityPeriod","BMQX");//保密期限
        put("DateOfIssue","QFRQ");//签发日期
        put("aggregationLevel","TYPE");//聚合层次
        put("nameOfFilingUnit","GDSJ");//归档单位名称
        put("filingDepartmentName","GDCS");//归档部门名称
        put("filingDepartmentCode","TITLE");//归档部门代码//TODO
        put("businessClass","WSJUANFLH");//业务类别
        put("generationYear","ND");//生成年份
        put("storagePeriod","BGQX");//保管期限
        put("language","YZ");//语种
        //put("id","TITLE");//id
    }};
    private final Map<String,String> efileMap=new HashMap<String,String>(){{
        //put("id","TITLE");//id
        put("attachmentName","REAL_DOC_NAME");//文件名称
        put("attachmentType","DOC_FILE_TYPE");//文件类型 pdf
        //put("attachmentPath","TITLE");//路径
        put("electronicSignature","DZQM");//电子签名
        put("signatureRule","QMGZ");//签名规则
        put("signatureDate","QMSJ");//签名日期
        put("signer","QMR");//签名人
        put("signatureResult","QMJG");//签名结果
        put("certificate","ZS");//证书
        put("certificateCitation","ZSYZ");//证书引证
        put("signatureAlgorithmIdentification","QMSF");//签名算法标识
        put("fileSummaryValue","WJZYZ");//文件摘要值
        put("sm3secretKey","SECRETKEY");//sm3秘钥
    }};
    Logger logger = LoggerFactory.getLogger(DetectionApiServiceImpl.class);

    @Override
    public Map detection(MultipartFile file, String code, String tenantCode) throws Exception {

        //拿到文件
        String absPath = detectionUrl + File.separator + new Date().getTime() + ".zip";
        File desc = new File(absPath);
        try {
            if (!desc.exists()) {
                if (!desc.getParentFile().exists()) {
                    desc.getParentFile().mkdirs();
                }
            }
            file.transferTo(Paths.get(absPath));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        //生成记录
        Long jlId = SnowflakeIdGenerator.generateId();
        ReceiveRecord receiveRecord = new ReceiveRecord();
        receiveRecord.setTenantCode(tenantCode);
        receiveRecord.setName(file.getName());
        receiveRecord.setCode(code);
        receiveRecord.setId(jlId);
        receiveRecord.setPath(absPath);
        receiveRecord.setState("0");
        receiveRecord.setCreateTime(new Date());
        receiveRecordMapper.insertReceiveRecord(receiveRecord);
         //对包进行检测
        return detectionMsgs( code, tenantCode, desc, jlId);
    }
    public Map detectionMsgs(String code,String tenantCode,File desc,Long jlId) throws Exception {
        List<DetailLogs> detailLogsList = new ArrayList<>();

        //查看是否有检测项
        DetectionScheme detectionScheme = detectionSchemeMapper.selectDetectionSchemeByCode(code, tenantCode + DetectionScheme.BIGTABLENAME);
        List<DetectionObject> detectionObjectList = detectionObjectMapper.selectDetectionObjectListByCode(code, tenantCode + DetectionScheme.BIGTABLENAME, tenantCode + DetectionObject.BIGTABLENAME, tenantCode + DetectionItem.BIGTABLENAME, tenantCode + TenantMdataList.BIGTABLENAME);
        if (detectionObjectList.size() <= 0) {
            throw new ServiceException("该方案未配置检测项！");
        }
        Long categoryId = detectionScheme.getCategoryId();
        //----将文件解压
        String encode = sysConfigService.selectConfigByCode("DECOMPRESSION_ENCODING", tenantCode);
        if (!StringUtils.isNotEmpty(encode) || "null".equals(encode))
            encode = "UTF-8";
        String newPath = desc.getParent() + File.separator + "detection" + File.separator + (desc.getName().substring(0, desc.getName().lastIndexOf(".")));
        FileService.decompress(desc.getAbsolutePath(), newPath, encode);  //解压文件
        //-----------进行解析文件以及进行四性检测
        TenantCategory category = tenantCategoryMapper.selectTenantCategoryByID(categoryId, tenantCode + TenantCategory.BIGTABLENAME);
        Integer type = category.getType();
        //检测Id
        Long sxId = SnowflakeIdGenerator.generateId();
        Map<String, Object> map = new HashMap<>();
        //对文件进行解析
        map = traverseFiles(new File(newPath), categoryId, tenantCode, detectionObjectList, sxId, map);

        detailLogsList.addAll(map.get("detailLogsList") == null ? new ArrayList<DetailLogs>() : (Collection<? extends DetailLogs>) map.get("detailLogsList"));
        //验证连续性
        String daType = "0";
        List<Map<String, Object>> lxList = (List<Map<String, Object>>) map.get("AJH");
        if (lxList != null && lxList.size() > 0) {
            //说明是卷
            daType = "1";
        } else {
            //说明是件
            lxList = (List<Map<String, Object>>) map.get("JH");
        }
        int failCount = map.get("failCount") == null ? 0 : Integer.parseInt(map.get("failCount").toString());
        //连续性检测单写一个
        Map map1 = detectionUtils.getLxMaps();
        Class<?> clazz = Class.forName("cn.yuanqiao.archive.api.util.DetectionUtils"); // 使用你的实际包名
        //使用反射去做验证
        for (DetectionObject detectionObject : detectionObjectList) {
            if (detectionObject.getIsPass().equals("0") && map1.containsKey(String.valueOf(detectionObject.getdId()))) {
                // 获取 Method 对象
                Method method = clazz.getMethod((String) map1.get(String.valueOf(detectionObject.getdId())), Map.class, List.class, JSONObject.class);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("sxId", sxId);
                jsonObject1.put("dId", detectionObject.getdId());
                jsonObject1.put("daType", daType);
                jsonObject1.put("lxList", lxList);
                jsonObject1.put("tenantCode", tenantCode);
                jsonObject1.put("categoryId", categoryId);
                Object result = method.invoke(detectionUtils, null, detectionObject.getDetectionItemList(), jsonObject1);
                if (result instanceof Integer) {
                    failCount += Integer.parseInt(result.toString());
                } else if (result instanceof Map) {
                    failCount += Integer.parseInt(((Map<?, ?>) result).get("failCount").toString());
                    detailLogsList.addAll((Collection<? extends DetailLogs>) ((Map<?, ?>) result).get("detailLogs"));
                }
            }
            //增加检测记录
        }

        if (detailLogsList.size() > 0) {
            detailLogsMapper.inserDetailLogsList(detailLogsList, tenantCode + DetailLogs.BIGTABLENAME);
        }
        //生成记录
        DetailLogs detailLogs = new DetailLogs();
        detailLogs.setpId(sxId);
        detailLogs.setTableName(tenantCode + DetailLogs.BIGTABLENAME);
        List<DetailLogs> detailLogLists = detailLogsMapper.selectDetailLogsList(detailLogs);
        List<InspectionLogs> list = new ArrayList<>();
        for (DetectionObject detectionObject1 : detectionObjectList) {
            List<DetailLogs> detailLogLists1 = detailLogLists.stream()
                    .filter(detailLog -> String.valueOf(detailLog.getdId()).equals(String.valueOf(detectionObject1.getdId())))
                    .collect(Collectors.toList());
            Set<String> set = detailLogLists1.stream()
                    .map(d -> {
                        if (type == 0) {
                            return d.getCheckDh();
                        } else if (type == 1 || type == 3) {
                            return StringUtils.isEmpty(d.getCheckParentDh()) ? d.getCheckDh() : d.getCheckParentDh();
                        } else {
                            // 根据您的需求，可能需要处理其他 type 值，或者抛出一个异常
                            throw new IllegalArgumentException("Unknown type: " + type);
                        }
                    })
                    .collect(Collectors.toSet());
            //判断有多少条档案失败
            if (detailLogLists1.size() > 0) {
                InspectionLogs inspectionLogs = new InspectionLogs();
                inspectionLogs.setId(SnowflakeIdGenerator.generateId());
                inspectionLogs.setDetectionTime(DateUtils.getNowDate());
                inspectionLogs.setDetectionResult("0");
                inspectionLogs.setdId(detectionObject1.getdId());
                inspectionLogs.setpId(sxId);
                inspectionLogs.setFailNum(set.size() + "");
                inspectionLogs.setIsPass(detectionObject1.getIsPass());
                list.add(inspectionLogs);
            } else {
                InspectionLogs inspectionLogs = new InspectionLogs();
                inspectionLogs.setId(SnowflakeIdGenerator.generateId());
                inspectionLogs.setDetectionTime(DateUtils.getNowDate());
                inspectionLogs.setDetectionResult("1");
                inspectionLogs.setdId(detectionObject1.getdId());
                inspectionLogs.setpId(sxId);
                inspectionLogs.setFailNum("");
                inspectionLogs.setIsPass(detectionObject1.getIsPass());
                list.add(inspectionLogs);
            }

        }
        if (list.size() > 0) {
            inspectionLogsMapper.insertBatchInspectionLogs(list, tenantCode + InspectionLogs.BIGTABLENAME);
        }
        InspectionRecords inspectionRecords = new InspectionRecords();
        inspectionRecords.setTableName(tenantCode + InspectionRecords.BIGTABLENAME);
        inspectionRecords.setIsDel(0);
        inspectionRecords.setDetectionTime(DateUtils.getNowDate());
        if (failCount > 0) {
            inspectionRecords.setDetectionResult("0");

        } else {
            inspectionRecords.setDetectionResult("1");

        }
        inspectionRecords.setId(sxId);
        inspectionRecords.setDetectionLink(detectionScheme.getPhase());
        inspectionRecords.setCategoryId(categoryId);
        //预归档无档号
        if (StringUtils.isEmpty(map.get("dh").toString())) {
            inspectionRecords.setDetectionDh("");

        } else {
            inspectionRecords.setDetectionDh(map.get("dh").toString().substring(0, map.get("dh").toString().length() - 1));

        }
        //  inspectionRecords.setCreateId(SecurityUtils.getUserId());
        inspectionRecordsMapper.insertInspectionRecords(inspectionRecords);
        String result="0";
        if (failCount > 0) {
            result="0";
        } else {
            result="1";
        }
        //识别完成

        ReceiveRecord receiveRecord1 = new ReceiveRecord();
        receiveRecord1.setId(jlId);
        receiveRecord1.setDetectionTime(new Date());
        receiveRecord1.setState("1");
        receiveRecord1.setSxId(sxId);
        receiveRecord1.setResult(result);
        receiveRecordMapper.updateReceiveRecord(receiveRecord1);

        //如果count大于0
        Map map2 = new HashMap();
        map2.put("result",result);
        map2.put("sxId", sxId);
        return map2;
    }

    @Override
    public String zipExport(Long id, String tenantCode) {
        //获取值并进行打包

        InspectionRecords inspectionRecords1 = inspectionRecordsMapper.selectInspectionRecordsById(id, tenantCode + InspectionRecords.BIGTABLENAME);
        Document dast = createTitleXml(inspectionRecords1, tenantCode);
        //生成文件
        String xmlPath = detectionUrl + File.separator + "xml" + File.separator;
        String path = "";
        // writer(path,dast);
        try {
            path = writer(xmlPath, dast);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return path;
    }

    @Override
    public Map<String,Object> receive(MultipartFile file, String code, String tenantCode) {
        //生成一个日志
        //入库
        String absPath = detectionUrl + File.separator + new Date().getTime() + ".zip";
        File desc = new File(absPath);
        try {
            if (!desc.exists()) {
                if (!desc.getParentFile().exists()) {
                    desc.getParentFile().mkdirs();
                }
            }
            file.transferTo(Paths.get(absPath));
        } catch (Exception e) {
            e.printStackTrace();

        }
        //生成记录
        Long jlId = SnowflakeIdGenerator.generateId();
        ReceiveRecord receiveRecord = new ReceiveRecord();
        receiveRecord.setTenantCode(tenantCode);
        receiveRecord.setName(file.getName());
        receiveRecord.setCode(code);
        receiveRecord.setId(jlId);
        receiveRecord.setPath(absPath);
        receiveRecord.setState("0");
        receiveRecord.setCreateTime(new Date());
        receiveRecordMapper.insertReceiveRecord(receiveRecord);
        Map<String,Object> map=new HashMap<>();
        map.put("packageId",jlId);
        return map;

    }

    @Override
    public void detectionTask(String tenantCode) throws Exception {
       ReceiveRecord receiveRecord=new ReceiveRecord();
       receiveRecord.setState("0");
       receiveRecord.setTenantCode(tenantCode);
       List<ReceiveRecord> list=receiveRecordMapper.selectReceiveRecordList(receiveRecord);
       for(ReceiveRecord record:list){
           File file=new File(record.getPath());
           if(file.exists()){
               Map map=detectionMsgs(record.getCode(),tenantCode,file,record.getId());
               //调用第三方接口返回检测结果
               //receiveMsg(map);

           }
       }
    }

    private void receiveMsg(Map map) {
      //需要第三方出接口文档



    }

    private Document createTitleXml(InspectionRecords inspectionRecords, String tenantCode) {
        Document document = DocumentHelper.createDocument();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Element root = document.addElement("四性检测");
        Element jl = root.addElement("四性检测记录");
        String link = inspectionRecords.getDetectionLink();

        if (link.equals("0")) {
            link = "归档阶段";
        } else if (link.equals("1")) {
            link = "移交阶段";
        } else if (link.equals("2")) {
            link = "长期阶段";
        } else if (link.equals("4")) {
            link = "预归档";
        }
        String result = inspectionRecords.getDetectionResult();
        if (result.equals("0")) {
            result = "不通过";
        } else if (result.equals("1")) {
            result = "通过";
        }

        jl.addElement("检测阶段").addText(link);
        jl.addElement("检测结果").addText(result);
        jl.addElement("检测时间").addText(inspectionRecords.getDetectionTime() == null ? "" : sdf.format(inspectionRecords.getDetectionTime()));
        jl.addElement("检测门类").addText(inspectionRecords.getCategoryId().toString());
        jl.addElement("检测档号").addText((null==inspectionRecords.getDetectionDh()?"未检测到档号":inspectionRecords.getDetectionDh()));
        Element jg = root.addElement("检测结果");
        //获取全部的检测项
        InspectionLogs in = new InspectionLogs();
        in.setpId(inspectionRecords.getId());
        in.setTableName(tenantCode + InspectionLogs.BIGTABLENAME);
        List<InspectionLogs> inspectionLogsList = inspectionLogsMapper.selectInspectionLogsList(in);
        DetailLogs detailLogs = new DetailLogs();
        detailLogs.setTableName(tenantCode + DetailLogs.BIGTABLENAME);
        detailLogs.setpId(inspectionRecords.getId());
        List<DetailLogs> detailLogsList = detailLogsMapper.selectDetailLogsList(detailLogs);
        for (InspectionLogs inspectionLogs : inspectionLogsList) {
            //遍历
            Element jcx = jg.addElement("检测项");
            //通过id获取到内容
            String jcnr = inspectionLogsMapper.getDetectionContent(inspectionLogs.getdId());
            jcx.addElement("检测内容").addText(jcnr);
            String jcjg = inspectionLogs.getDetectionResult();
            if (jcjg.equals("0")) {
                jcjg = "不通过";
            } else if (jcjg.equals("1")) {
                jcjg = "通过";
            }
            jcx.addElement("检测结果").addText(jcjg);
            jcx.addElement("检测时间").addText(sdf.format(inspectionLogs.getDetectionTime()));
            String failNum = inspectionLogs.getFailNum();
            jcx.addElement("失败数量").addText(null==failNum?"0":failNum);
            if (StringUtils.isNotEmpty(failNum) && Integer.parseInt(failNum) > 0) {
                Element fails = jcx.addElement("失败原因集合");
                List<DetailLogs> detailLogLists1 = detailLogsList.stream()
                        .filter(detailLog -> String.valueOf(detailLog.getdId()).equals(String.valueOf(inspectionLogs.getdId())))
                        .collect(Collectors.toList());
                for (DetailLogs detailLogs1 : detailLogLists1) {
                    Element fail = fails.addElement("失败原因");
                    fail.addElement("原因").addText(detailLogs1.getMessage());
                    fail.addElement("档号").addText(null==detailLogs1.getCheckDh()?"未检测到档号":detailLogs1.getCheckDh());
                }
            }


        }

        return document;
    }

    /**
     * 写入文件
     *
     * @param path
     * @param document
     * @throws IOException
     */
    public String writer(String path, Document document) throws IOException {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        // 紧凑的格式
        // OutputFormat format = OutputFormat.createCompactFormat();
        // 排版缩进的格式
        OutputFormat format = OutputFormat.createPrettyPrint();
        // 设置编码
        format.setEncoding("UTF-8");
        // 创建XMLWriter对象,指定了写出文件及编码格式
        // XMLWriter writer = new XMLWriter(new FileWriter(new
        // File("src//a.xml")),format);
        path += new Date().getTime() + ".xml";
        XMLWriter writer = new XMLWriter(
                new OutputStreamWriter(new FileOutputStream(new File(path)), "UTF-8"), format);
        // 写入
        writer.write(document);
        // 立即写入
        writer.flush();
        // 关闭操作
        writer.close();
        return path;
    }

    private Map<String, Object> traverseFiles(File directory, Long categoryId, String tenantCode, List<DetectionObject> detectionObjectList, Long sxId, Map<String, Object> map) throws Exception {
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    map = traverseFiles(file, categoryId, tenantCode, detectionObjectList, sxId, map);
                }
            }
        } else {
            //文件类型
            if (directory.getName().toLowerCase().endsWith(".xml")&&!"说明文件.xml".equals(directory.getName())) {
                map = analysisArchive(directory, categoryId, tenantCode, detectionObjectList, sxId, map);
            }
        }
        return map;
    }

    private Map<String, Object> analysisArchive(File xmlFile, Long categoryId, String tenantCode, List<DetectionObject> detectionObjectList, Long sxId, Map<String, Object> map) throws Exception {
        int failCount = map.get("failCount") == null ? 0 : Integer.parseInt(map.get("failCount").toString());
        List<DetailLogs> detailLogsList = map.get("detailLogsList") == null ? new ArrayList<DetailLogs>() : (List<DetailLogs>) map.get("detailLogsList");
        List<Map<String, String>> JHlist = map.get("JH") == null ? new ArrayList<>() : (List<Map<String, String>>) map.get("JH");
        List<Map<String, String>> AJHList = map.get("AJH") == null ? new ArrayList<>() : (List<Map<String, String>>) map.get("AJH");
        String dh1 = map.get("dh") == null ? "" : map.get("dh").toString();
        //通过档号判断门类
        JSONObject archiveData = XMLtoJsonUtils.startXMLToJSON(xmlFile);  //xml 文件解析成 JSON格式
        logger.info(archiveData.toJSONString());
        //档案类型
        //String archiveType = archiveData.getJSONObject("documentSendList").getJSONObject("documentSend").getString("aggregationLevel");
        String archiveType ="文件";
        JSONObject dh = null;
        //String qzh = dh.getString("全宗号");
        //String code = dh.getString("档案门类");
        Integer type = 0;
        /*Boolean xmBl = archiveData.getJSONObject("被签名对象").getJSONObject("封装内容").getJSONObject("档案实体块").getJSONObject("内容描述").containsKey("项目层");
        if (xmBl) {
            type = 3;
        } else if ("组卷".equals(archiveType)) {
            type = 1;
        } else if ("文件".equals(archiveType)) {
            type = 0;
        }*/
        //确定门类
        TenantCategory category = tenantCategoryMapper.selectTenantCategoryByID(categoryId, tenantCode + TenantCategory.BIGTABLENAME);
        if (!type.toString().equals(category.getType().toString())) {
            throw new ServiceException("档案类型不一致！");
        }
        if (category != null) {
            String dzdah = "";
            map.put("dh", dh1 + dzdah + ",");
            TenantMdataList mdataListSelect = new TenantMdataList();
            mdataListSelect.setTableName(tenantCode + TenantMdataList.BIGTABLENAME);
            List<TenantMdataList> mdataLists = mdataListMapper.selectTenantMdataListListByCategoryId(mdataListSelect, category.getId(), tenantCode + TenantCategory.BIGTABLENAME);
            String jianDhzd = "";
            //解析卷或者项目
            if (category.getType() == 3 || category.getType() == 1) {
                //档案实体块
                JSONObject juanJson = archiveData.getJSONObject("被签名对象").getJSONObject("封装内容").getJSONObject("档案实体块").getJSONObject("内容描述");
                jianDhzd = archiveData.getJSONObject("被签名对象").getJSONObject("封装内容").getJSONObject("档案实体块").getJSONObject("档号").getString("件档号组成字段");
                Map<String, String> colData = new HashMap<>();
                colData.put("DH", dzdah);
                for (TenantMdataList mdataList : mdataLists) {
                    if (mdataList.getType() == 1 && juanJson.containsKey(mdataList.getFieldCaption())) {
                        if (mdataList.getShowType() == 5) {
                            colData.put(mdataList.getFieldName(), getDictVal(mdataList.getFieldName(), juanJson.getString(mdataList.getFieldCaption()), tenantCode));
                        } else {
                            colData.put(mdataList.getFieldName(), juanJson.getString(mdataList.getFieldCaption()));
                        }
                    }
                }
                Map<String, Object> maps0 = detectionMsg(colData, detectionObjectList, sxId, "1", null, tenantCode, categoryId, "");
                failCount += Integer.parseInt(maps0.get("failCount") == null ? "0" : maps0.get("failCount").toString());
                detailLogsList.addAll(maps0.get("detailLogsList") == null ? new ArrayList<DetailLogs>() : (Collection<? extends DetailLogs>) maps0.get("detailLogsList"));
                AJHList.add(colData);
                map.put("AJH", AJHList);
            }
            //处理件层
            String daType = "";
            JSONArray jianArray = new JSONArray();
            if (category.getType() == 0) {
                jianArray.add(archiveData.getJSONObject("documentSendList").getJSONObject("documentSend"));
                daType = "0";
            } else {
                JSONObject jsonObjectnew = archiveData.getJSONObject("documentSendList").getJSONObject("documentSend").getJSONObject("档案实体块").getJSONObject("内容描述");
                if (jsonObjectnew.getJSONObject("件层集") != null && jsonObjectnew.containsKey("件层集")) {
                    jianArray = jsonObjectnew.getJSONObject("件层集").getJSONArray("件层");
                }
                daType = "2";
            }
            List<Map<String, String>> files = new ArrayList<>();
            for (int i = 0; i < jianArray.size(); i++) {
                JSONObject jian = jianArray.getJSONObject(i);
                Map<String, String> colData = new HashMap<>();

                /*for (TenantMdataList mdataList : mdataLists) {
                    if (mdataList.getType() == 0 && jian.containsKey(mdataList.getFieldCaption())) {
                        if (mdataList.getShowType() == 5) {
                            colData.put(mdataList.getFieldName(), getDictVal(mdataList.getFieldName(), jian.getString(mdataList.getFieldCaption()), tenantCode));
                        } else {
                            colData.put(mdataList.getFieldName(), jian.getString(mdataList.getFieldCaption()));
                        }
                    }
                }*/
                for (Map.Entry<String, String> entry : jianMap.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    for (TenantMdataList mdataList : mdataLists) {
                        if (mdataList.getType() == 0 && value.equals(mdataList.getFieldName())) {
                            if (mdataList.getShowType() == 5) {
                                colData.put(value, getDictVal(mdataList.getFieldName(), jian.getString(key), tenantCode));
                            } else {
                                colData.put(value, jian.getString(key));
                            }
                        }
                    }
                }
                dzdah="";
                //daType:2 说明是卷内件 卷内件有卷档号
                if ("2".equals(daType)) {
                    colData.put("parentDh", dzdah);
                    if (!colData.containsKey("DH")) {
                        //获取档号
                        String jdh = getJDH(colData, categoryId, tenantCode, dzdah, jianDhzd, jian);
                        colData.put("DH", jdh);
                    }
                } else {
                    if (!colData.containsKey("DH")) {
                        colData.put("DH", dzdah);
                    }

                }
                files.add(colData);
                //检测包里的元数据方案
                Map<String, Object> maps = detectionMsg(colData, detectionObjectList, sxId, daType, null, tenantCode, categoryId, colData.get("parentDh") == null ? "" : colData.get("parentDh"));
                failCount += Integer.parseInt(maps.get("failCount") == null ? "0" : maps.get("failCount").toString());
                detailLogsList.addAll(maps.get("detailLogsList") == null ? new ArrayList<DetailLogs>() : (Collection<? extends DetailLogs>) maps.get("detailLogsList"));
                //解析电子文件
                Map<String, Object> maps1 = saveEFile(xmlFile, jian, category, tenantCode, mdataLists, daType, detectionObjectList, sxId, colData.get("DH"), colData.get("parentDh") == null ? "" : colData.get("parentDh"));

                failCount += Integer.parseInt(maps1.get("failCount") == null ? "0" : maps1.get("failCount").toString());
                detailLogsList.addAll(maps1.get("detailLogsList") == null ? new ArrayList<DetailLogs>() : (Collection<? extends DetailLogs>) maps1.get("detailLogsList"));
                 //用于检测jh和ajh的连续性
                if ("0".equals(daType)) {
                    JHlist.add(colData);
                }

            }
            if (JHlist.size() > 0) {
                map.put("JH", JHlist);
            }
            if (!"0".equals(daType)) {
                //对卷内件进行判断
                Map<String, Object> maps2 = detectionMsg(null, detectionObjectList, sxId, daType, files, tenantCode, categoryId, dzdah);
                failCount += Integer.parseInt(maps2.get("failCount") == null ? "0" : maps2.get("failCount").toString());
                detailLogsList.addAll(maps2.get("detailLogsList") == null ? new ArrayList<DetailLogs>() : (Collection<? extends DetailLogs>) maps2.get("detailLogsList"));

            }
            map.put("failCount", failCount);
            map.put("detailLogsList", detailLogsList);
        }
        return map;
    }

    private String getJDH(Map<String, String> colData, Long categoryId, String tenantCode, String dzdah, String jianDhzd, JSONObject jian) {
        //获取档号规则
        List<Map> list1 = new ArrayList<>();
        String rq = colData.get("RQ") == null ? "" : colData.get("RQ");
        if (StringUtils.isNotEmpty(rq)) {
            rq = rq.replaceAll("-", "").replaceAll("/", "");
            rq = addZero(rq);
        }
        if (!StringUtils.isEmpty(rq)) {
            list1 = detectionObjectMapper.getDhByRq(rq, tenantCode.toUpperCase(), categoryId);
        }
        if (list1.size() <= 0) {
            list1 = detectionObjectMapper.getDh(rq, tenantCode.toUpperCase(), categoryId);
        }
        JSONObject json = new JSONObject();
        TenantCodeList yqdaCodelistModel = new TenantCodeList();
        yqdaCodelistModel.setTableName(tenantCode + TenantCodeList.BIGTABLENAME);
        yqdaCodelistModel.setArchivalcodeRuleId(Long.parseLong(list1.get(0).get("RULEID").toString()));
        List<TenantCodeList> yqdaCodelistModels = tenantCodeListMapper.selectYqdaCodelistModelList(yqdaCodelistModel);
        List<String> ziduanarr = new ArrayList<>();
        List<String> fuhaoarr = new ArrayList<>();
        List<String> bulingarr = new ArrayList<>();
        for (int i = 0; i < yqdaCodelistModels.size(); i++) {
            if (yqdaCodelistModels.get(i).getVFETYPE().equals("v") && "著录项值".equals(yqdaCodelistModels.get(i).getType())) {//件
                ziduanarr.add(yqdaCodelistModels.get(i).getNodeValue());
                bulingarr.add(String.valueOf(yqdaCodelistModels.get(i).getLen()));
            } else if (yqdaCodelistModels.get(i).getVFETYPE().equals("v") && "固定值".equals(yqdaCodelistModels.get(i).getType())) { //卷 或 项目
                fuhaoarr.add(yqdaCodelistModels.get(i).getNodeValue());
            } else if ("e".equals(yqdaCodelistModels.get(i).getVFETYPE())) {
                json.put("filelianjie", yqdaCodelistModels.get(i).getNodeValue());
            } else {
                if ("著录项值".equals(yqdaCodelistModels.get(i).getType())) {
                    json.put("jianziduan", yqdaCodelistModels.get(i).getNodeValue());
                    json.put("jianbuling", yqdaCodelistModels.get(i).getLen());
                } else {
                    json.put("jianlianjie", yqdaCodelistModels.get(i).getNodeValue());
                }
            }
        }
        json.put("ziduanarr", ziduanarr);
        json.put("fuhaoarr", fuhaoarr);
        json.put("bulingarr", bulingarr);
        TenantCodeRule yqdaCoderuleModel = tenantCodeRuleMapper.selectYqdaCoderuleModelById(Long.parseLong(list1.get(0).get("RULEID").toString()), tenantCode + TenantCodeRule.BIGTABLENAME);
        json.put("columnname", "f".equals("v") ? yqdaCoderuleModel.getfColumnname() : yqdaCoderuleModel.getvColumnname());
        json.put("jiancunchuziduan", yqdaCoderuleModel.getfColumnname());
        json.put("order", yqdaCoderuleModel.getOrderStr());
        json.put("filecunchuziduan", yqdaCoderuleModel.geteColumnname());
        if (!jian.containsKey(jianDhzd)) {
            throw new ServiceException(jianDhzd + "字段未勾选元数据项");
        }
        String zh = jian.getString(jianDhzd);
        String val = "";
        for (int m = 0; m < Integer.parseInt(json.getString("jianbuling")) - zh.length(); m++) {
            val += "0";
        }
        return dzdah + json.getString("jianlianjie") + val + zh;


    }

    private Map<String, Object> saveEFile(File xmlFile, JSONObject jian, TenantCategory category, String tenantCode, List<TenantMdataList> mdataLists, String daType, List<DetectionObject> detectionObjectList, Long sxId, String jianDH, String parentDh) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        //解析电子文件层
        JSONArray eFileJson = null;
        List<Map<String, String>> fileList = new ArrayList<>();
        if (jian.getJSONObject("attachmentList") != null) {
            eFileJson = objecttoarray(jian.getJSONObject("attachmentList").get("attachment"));
            for (int j = 0; j < eFileJson.size(); j++) {
                JSONObject eFileObject = eFileJson.getJSONObject(j);
                Map<String, String> map = new HashMap<>();
                /*for (TenantMdataList mdataList : mdataLists) {
                    if (mdataList.getType() == 2 && eFileObject.containsKey(mdataList.getFieldCaption())) {
                        if (mdataList.getShowType() == 5) {
                            map.put(mdataList.getFieldName(), getDictVal(mdataList.getFieldName(), eFileObject.getString(mdataList.getFieldCaption()), tenantCode));
                        } else {
                            map.put(mdataList.getFieldName(), eFileObject.getString(mdataList.getFieldCaption()));
                        }
                    }
                }*/
                for (Map.Entry<String, String> entry : efileMap.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    for (TenantMdataList mdataList : mdataLists) {
                        if (mdataList.getType() == 2 && value.equals(mdataList.getFieldName())) {
                            if (mdataList.getShowType() == 5) {
                                map.put(value, getDictVal(mdataList.getFieldName(), eFileObject.getString(key), tenantCode));
                            } else {
                                map.put(value, eFileObject.getString(key));
                            }
                        }
                    }
                }
                //   String filePath = extractPath(category, daId);  //存储的相对路径
                String fileName = map.get("REAL_DOC_NAME");
                String xmlPath = null;
                //如果非件层，获取的为说明文件同一路径下的+件档号 下的文件
                if (category.getType() != 0) {
                    xmlPath = xmlFile.getParent() + File.separator + jianDH + File.separator + fileName;  //归档包电子文件路径
                } else {
                    xmlPath = xmlFile.getParent() + File.separator + fileName;  //归档包电子文件路径
                }
                map.put("WJPATH", xmlPath);
                map.put("DH", "");
                fileList.add(map);
            }
        }

        Map<String, Object> maps = new HashMap<>();
        maps.put("failCount", 0);
        maps.put("detailLogsList", new ArrayList<DetailLogs>());
        if (fileList.size() > 0) {
            maps = detectionFile(fileList, detectionObjectList, sxId, daType, tenantCode, parentDh);
        }

        return maps;


    }


    /**
     * 字典项
     *
     * @param fieldName
     * @param dict
     * @return
     */
    private String getDictVal(String fieldName, String dict, String tenantCode) {
        String DictVal = "";
        Boolean bl = false;
        List<TenantSysDictData> list = sysDictTypeService.selectDictDataByTypeCode(fieldName, tenantCode);
        if (list != null && list.size() > 0) {
            if (dict != null) {
                for (TenantSysDictData dictData : list) {
                    if (dict.equals(dictData.getDictLabel())) {
                        DictVal = dictData.getDictValue();
                        bl = true;
                        break;
                    }
                }
            }
            if (!bl) {
                DictVal = dict;
            }
        } else {
            DictVal = dict;
        }

        return DictVal;
    }

    private com.alibaba.fastjson2.JSONArray objecttoarray(Object object) {
        if (object instanceof com.alibaba.fastjson2.JSONObject) {
            com.alibaba.fastjson2.JSONArray array = new com.alibaba.fastjson2.JSONArray(1);
            array.add(object);
            return array;
        } else if (object instanceof com.alibaba.fastjson2.JSONArray) {
            return (com.alibaba.fastjson2.JSONArray) object;
        }
        return null;
    }

    private Map<String, Object> detectionMsg(Map<String, String> colData, List<DetectionObject> detectionObjectList, Long sxId, String daType, List<Map<String, String>> list, String tenantCode, Long categoryId, String parentDh) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<DetailLogs> detailLogsList = new ArrayList();
        int failCount = 0;
        Map<String, String> map = detectionUtils.getMaps();
        if (colData == null && list != null) {
            map = detectionUtils.getLxMaps();
        }
        Class<?> clazz = Class.forName("cn.yuanqiao.archive.api.util.DetectionUtils"); // 使用你的实际包名
        //使用反射去做验证 因为不同检测方案 可以配置不同的检测项 此处使用反射调用
        for (DetectionObject detectionObject : detectionObjectList) {
            if (detectionObject.getIsPass().equals("0") && map.containsKey(String.valueOf(detectionObject.getdId()))) {
                // 获取 Method 对象
                Method method = clazz.getMethod(map.get(String.valueOf(detectionObject.getdId())), Map.class, List.class, JSONObject.class);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("sxId", sxId);
                jsonObject.put("dId", detectionObject.getdId());
                jsonObject.put("daType", daType);
                jsonObject.put("lxList", list);
                jsonObject.put("tenantCode", tenantCode);
                jsonObject.put("categoryId", categoryId);
                jsonObject.put("parentDh", parentDh);
//                DetectionUtils detectionUtils = new DetectionUtils();
                Object result = method.invoke(detectionUtils, colData, detectionObject.getDetectionItemList(), jsonObject);
                if (result instanceof Integer) {
                    failCount += Integer.parseInt(result.toString());
                } else if (result instanceof Map) {
                    failCount += Integer.parseInt(((Map<?, ?>) result).get("failCount").toString());
                    detailLogsList.addAll((Collection<? extends DetailLogs>) ((Map<?, ?>) result).get("detailLogs"));

                }

            }
        }
        //失败数 返回失败数以及失败项目内容
        Map<String, Object> maps = new HashMap<>();
        maps.put("failCount", failCount);
        maps.put("detailLogsList", detailLogsList);
        return maps;
    }

    private Map<String, Object> detectionFile(List<Map<String, String>> colData, List<DetectionObject> detectionObjectList, Long sxId, String daType, String tenantCode, String parentDh) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        int failCount = 0;
        List<DetailLogs> detailLogsList = new ArrayList();
        Map<String, String> map = detectionUtils.getFilesMaps();
        Class<?> clazz = Class.forName("cn.yuanqiao.archive.api.util.DetectionUtils"); // 使用你的实际包名
        //使用反射去做验证
        for (DetectionObject detectionObject : detectionObjectList) {
            if (detectionObject.getIsPass().equals("0") && map.containsKey(String.valueOf(detectionObject.getdId()))) {
                // 获取 Method 对象
                Method method = clazz.getMethod(map.get(String.valueOf(detectionObject.getdId())), List.class, List.class, JSONObject.class);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("sxId", sxId);
                jsonObject.put("dId", detectionObject.getdId());
                jsonObject.put("daType", daType);
                jsonObject.put("tenantCode", tenantCode);
                jsonObject.put("parentDh", parentDh);


//                DetectionUtils detectionUtils = new DetectionUtils();
                Object result = method.invoke(detectionUtils, colData, detectionObject.getDetectionItemList(), jsonObject);
                if (result instanceof Integer) {
                    failCount += Integer.parseInt(result.toString());
                } else if (result instanceof Map) {
                    failCount += Integer.parseInt(((Map<?, ?>) result).get("failCount").toString());
                    detailLogsList.addAll((Collection<? extends DetailLogs>) ((Map<?, ?>) result).get("detailLogs"));

                }

            }
        }
        //失败数
        Map<String, Object> maps = new HashMap<>();
        maps.put("failCount", failCount);
        maps.put("detailLogsList", detailLogsList);
        return maps;
    }

    //字符串不足8位末尾补零
    public String addZero(String str) {
        int length = str.length();
        if (length < 8) {
            int b = 8 - length;
            for (int i = 0; i < b; i++) {
                str += "0";
            }
            return str;
        }
        return str;
    }
}
